#pragma once
#include "iostream"
#include "vector"
#include "string"
using namespace std;
#include "RobotLogic.h"

class Substitute;

class LogicExpression
{
protected:
	string name;
	int type;
public:
	virtual bool isEqual(LogicExpression* expr){return false;};
	string getName(){return name;};
	bool isVar(){return type == 0;};
	bool isConst(){return type == 1;};
	bool isFunc(){return type == 2;};
	bool isList(){return type == 3;};
	virtual bool contain(LogicExpression* expr){return false;};
	virtual LogicExpression* applySubstitute(Substitute* sub){return this;};
	virtual void print()
	{
		//cout <<"["<<type <<"]"<< name;
		cout << name;
	};
};


class VarExpression :public LogicExpression
{
public:
	VarExpression(string _name);
	bool isEqual(LogicExpression* expr);
	bool contain(LogicExpression* expr);
	LogicExpression* applySubstitute(Substitute* sub);
};
class ConstExpression :public LogicExpression
{
private:
	int value;
public:
	int getValue(){return value;};
	ConstExpression(int _value);
	bool isEqual(LogicExpression* expr);
};
class FuncExpression :public LogicExpression
{
private:
	vector<LogicExpression*> listArguments;
public:
	FuncExpression(string _name);
	void setlistArguments(vector<LogicExpression*>);
	bool isEqual(LogicExpression* expr);
	LogicExpression* getArguments();
	LogicExpression* getSingleArgument();
	bool contain(LogicExpression* expr);
	LogicExpression* applySubstitute(Substitute* sub);
	void print();
	
};

class ListExpression :public LogicExpression
{
private:
	vector<LogicExpression*> listArguments;
public:
	ListExpression(vector<LogicExpression*> _listArguments);
	bool isEqual(LogicExpression* expr);
	LogicExpression* popFirst();
	bool contain(LogicExpression* expr);
	LogicExpression* applySubstitute(Substitute* sub);
};


